package com.example.task12vhourse;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Separator;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class KnightChessGUI extends Application {
    private static int BOARD_SIZE = 5;
    private static final int CELL_SIZE = 80;

    private int[][] field;

    private Button[][] cellButtons;

    private Button[][] cellWButtons;
    private int selectedX = -1;
    private int selectedY = -1;
    private int selectedMoves = 2;
    private String levels[] = {
            "FF2D00",
            "FFBD00",
            "ECFF00",
            "80FF00",
            "AFFFA3",
            "00FFB9",
            "49C2FF",
            "001FFF",
            "8B00FF",
            "FF00CD",
            "FF005D",
    };
    GridPane gridControlPane = new GridPane();
    GridPane gridWallsPane = new GridPane();

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Knight Chess");

        HBox panes = new HBox();
        panes.setAlignment(Pos.CENTER);

        Separator separator = new Separator();
        separator.setOrientation(Orientation.VERTICAL);
        separator.setLayoutX(10);

        panes.getChildren().add(gridControlPane);
        panes.getChildren().add(separator);
        panes.getChildren().add(gridWallsPane);

        gridControlPane.setAlignment(Pos.CENTER);
        gridWallsPane.setAlignment(Pos.CENTER);


        VBox controlBox = new VBox(10);
        TextField sizeTF = new TextField();
        sizeTF.setPromptText("Size");

        Button setSizeBtn = new Button();
        setSizeBtn.setText("Set size");
        setSizeBtn.setOnAction(e -> {
            BOARD_SIZE = Integer.parseInt(sizeTF.getText());
            field = new int[BOARD_SIZE][BOARD_SIZE];

            gridControlPane.getChildren().clear();
            gridWallsPane.getChildren().clear();

            cellButtons = new Button[BOARD_SIZE][BOARD_SIZE];

            cellWButtons = new Button[BOARD_SIZE][BOARD_SIZE];

            for (int i = 0; i < BOARD_SIZE; i++) {
                for (int j = 0; j < BOARD_SIZE; j++) {
                    Button cellButton = new Button();
                    cellButton.setPrefSize(CELL_SIZE, CELL_SIZE);
                    final int ii = i, jj = j;
                    cellButton.setOnAction(z -> {
                        handleCellClick(ii, jj);
                    });
                    cellButtons[i][j] = cellButton;
                    gridControlPane.add(cellButton, j, i);

                    Button wallCellButton = new Button();
                    wallCellButton.setPrefSize(CELL_SIZE, CELL_SIZE);
                    wallCellButton.setOnAction(z -> {
                        handleWallCellClick(ii, jj);
                    });

                    cellWButtons[i][j] = wallCellButton;
                    gridWallsPane.add(wallCellButton, j, i);

                }
            }
        });

        TextField stepsTF = new TextField();
        stepsTF.setPromptText("Steps");

        controlBox.setAlignment(Pos.CENTER);
        Button findButton = new Button("Find Reachable Cells");
        findButton.setOnAction(e -> {
            selectedMoves = Integer.parseInt(stepsTF.getText());
            findReachableCells();
        });
        controlBox.getChildren().add(sizeTF);
        controlBox.getChildren().add(setSizeBtn);
        controlBox.getChildren().add(stepsTF);
        controlBox.getChildren().add(findButton);


        Scene scene = new Scene(new javafx.scene.layout.VBox(10, panes, controlBox), 400, 500);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void handleWallCellClick(int x, int y) {
        if (field[x][y] == 1) {
            cellWButtons[x][y].setStyle("");
            field[x][y] = 0;
        }else{
            field[x][y] = 1;
            cellWButtons[x][y].setStyle("-fx-background-color: red;");
        }
    }

    private void handleCellClick(int x, int y) {
        if (selectedX == x && selectedY == y) {
            // Deselect the cell if clicked again
            cellButtons[x][y].setStyle("");
            selectedX = -1;
            selectedY = -1;
        } else {
            if (selectedX != -1 && selectedY != -1) {
                cellButtons[selectedX][selectedY].setStyle("");
            }
            cellButtons[x][y].setStyle("-fx-background-color: #00ff00;");
            selectedX = x;
            selectedY = y;
        }
    }

    private void findReachableCells() {
        if (selectedX != -1 && selectedY != -1 && selectedMoves > 0) {
            KnightChess.Cell reachableCells = KnightChess.findReachableCells(field, selectedX, selectedY, selectedMoves);

            for (int i = 0; i < BOARD_SIZE; i++) {
                for (int j = 0; j < BOARD_SIZE; j++) {
                    cellButtons[i][j].setStyle("");
                    cellButtons[i][j].setText("");
                }
            }
            Thread thread = new Thread(() ->
            {
                draw(reachableCells.childs, 1, "");
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        cellButtons[reachableCells.x][reachableCells.y].setStyle("-fx-background-color: #" + levels[0] + ";");
                        cellButtons[reachableCells.x][reachableCells.y].wrapTextProperty().setValue(true);
                        cellButtons[reachableCells.x][reachableCells.y].setText("♘");
                        cellButtons[reachableCells.x][reachableCells.y].setFont(new Font(10));
                    }
                });
            });
            thread.start();
        }
    }
    private void draw(List<KnightChess.Cell> li, int level, String text) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        if (li.size() == 0)
            return;
        for (int j = 0; j < li.size(); j++) {
            KnightChess.Cell i = li.get(j);
            int finalJ = j;
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    cellButtons[i.x][i.y].setStyle("-fx-background-color: #" + levels[level] + ";");
                    cellButtons[i.x][i.y].wrapTextProperty().setValue(true);
                    cellButtons[i.x][i.y].setText("♘" + text + "." + finalJ);
                    cellButtons[i.x][i.y].setFont(new Font(10));
                }
            });
            if (i.childs.size() > 0)
                draw(i.childs, level + 1, text + "." + j);
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}
